#include <stdio.h>
#include <fstream>
#include "game.h"
#include "cli.h"
#include "player.h"
#include "enemy.h"

using namespace std;

int timer = 0;

// data-driven initialization... reads a file to generate game state
Game::Game(char * a_initialGameDataFile)
{
	// load map data
	
	m_map.load(a_initialGameDataFile);
	m_playerList.add(new Player(0, 0, 1));
	m_playerList.add(new Enemy(m_map.getWidth()/2, m_map.getHeight()/2, 2, 200));
}

// find a player from the player list at the given location
Player * Game::getPlayerAt(int a_x, int a_y)
{
	Player * p;
	for(int i = 0; i < m_playerList.getSize(); ++i)
	{
		p = (Player*)m_playerList.get(i);
		if(p->isAt(a_x, a_y))
		{
			return p;
		}
	}
	return 0;
}

// a simple, static draw method. draws to the windows console
void Game::draw()
{
	// start the cursor at the top-left corner
	gotoxy(0, 0);
	char c;
	Player * p;
	// draw the player/enemy, and map data (in that order) at each square of the map
	for(int y = 0; y < m_map.getHeight(); ++y)
	{
		for(int x = 0; x < m_map.getWidth(); ++x)
		{
			// if there is a player/enemy here
			p = getPlayerAt(x,y);
			if(p)
			{
				// that is what we're going to draw
				setcolor(COLOR_WHITE, COLOR_BLACK);
				if(timer > 0)
					setcolor(timer, COLOR_BLACK);
				c = p->getIcon();
			}
			else
			{
				setcolor(COLOR_GREEN, COLOR_BLACK);
				c = m_map.getAt(x, y);
			}
			// draw it
			printf("%c", c);
		}
		printf("\n");
	}
}

int translateKeyPressToMove(char a_keyPress)
{
	// 'w', 'a', 's', and 'd' are used to move the player
	switch(a_keyPress)
	{
	case 'w':	return PLAYER_MOVE_UP;
	case 'a':	return PLAYER_MOVE_LEFT;
	case 's':	return PLAYER_MOVE_DOWN;
	case 'd':	return PLAYER_MOVE_RIGHT;
	}
	return PLAYER_MOVE_NONE;
}

// input handler. takes in a key press as a character
void Game::handleInput(char k_press)
{
	Player * p = (Player*)m_playerList.get(0);
	p->setNextMove(translateKeyPressToMove(k_press));
}

// update the game logic
void Game::update(int a_ms)
{
	timer -= a_ms;
	Player * p;
	Enemy * e;
	int oldx, oldy;
	for(int i = 0; i < m_playerList.getSize(); ++i)
	{
		p = (Player*)m_playerList.get(i);
		oldx = p->getX();
		oldy = p->getY();
		p->update(a_ms);
		if(p->getX() < 0 || p->getX() >= m_map.getWidth()
		|| p->getY() < 0 || p->getY() >= m_map.getHeight()
		|| m_map.getAt(p->getX(), p->getY()) == '#')
		{
			p->setX(oldx);
			p->setY(oldy);
		}
	}
	p = (Player*)m_playerList.get(0);
	e = (Enemy*)m_playerList.get(1);
	if(e->isAt(p->getX(), p->getY()))
	{
		if(timer > 0)
		{
			printf("win");
		}
		else
		{
			printf("fail");
		}
		exit(0);
	}
	if(m_map.getAt(p->getX(), p->getY()) == '*')
	{
		timer = 5000;
	}
}

// a destructor to clean up game data
Game::~Game()
{
	// no data is dynamically allocated, so nothing needs to be cleaned up
}
